package com.imflea.zero.service.user.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.imflea.zero.constant.QxContant;
import com.imflea.zero.dto.IdDto;
import com.imflea.zero.exception.BizException;
import com.imflea.zero.model.dao.user.WebUserInfoMapper;
import com.imflea.zero.model.entity.qx.QxUserAccess;
import com.imflea.zero.model.entity.user.WebUserAccount;
import com.imflea.zero.model.entity.user.WebUserInfo;
import com.imflea.zero.model.entity.user.dto.WebUserInfoDto;
import com.imflea.zero.model.entity.user.vo.WebUserInfoDetailVo;
import com.imflea.zero.service.qx.IQxUserAccessService;
import com.imflea.zero.service.user.IWebUserAccountService;
import com.imflea.zero.service.user.IWebUserInfoService;
import com.imflea.zero.util.ZeroCacheUtils;
import com.imflea.zero.util.base.CommonUtils;
import com.imflea.zero.utils.SessionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 微信端用户基本信息 服务实现类
 * </p>
 *
 * @author xiangbaoyu
 * @since 2021-09-13
 */
@Service
public class WebUserInfoServiceImpl extends ServiceImpl<WebUserInfoMapper, WebUserInfo> implements IWebUserInfoService {
    @Autowired
    private IQxUserAccessService userAccessService;
    @Autowired
    private IWebUserAccountService webUserAccountService;


    @Override
    public Boolean updateWebUserInfo(WebUserInfo entity) {

        if (CommonUtils.isNull(entity.getId()) || CommonUtils.isNull(entity.getOpenId())) {
            throw new BizException("用户ID或OpenId为空,请确认请求数据");
        }

        entity.setTenantId(SessionUtils.getTenantId());
        return this.saveOrUpdate(entity);
    }

    @Override
    public PageInfo<WebUserInfo> queryPage(WebUserInfoDto dto) {
        Integer pageIndex = dto.getPageNum();
        Integer pageSize = dto.getPageSize();
        String tenantId = SessionUtils.getTenantId();
        QueryWrapper<WebUserInfo> queryWrapper = new QueryWrapper<>();
        String nickName = dto.getNickName();
        String cellNum = dto.getCellNum();
        if (!CommonUtils.isNull(nickName)) {
            queryWrapper.like("nick_name", nickName);
        }
        if (!CommonUtils.isNull(cellNum)) {
            queryWrapper.eq("cell_num", cellNum);
        }
        queryWrapper.eq("tenant_id", tenantId);
//        queryWrapper.isNotNull("gender");
        PageHelper.startPage(pageIndex, pageSize);
        queryWrapper.orderByDesc("create_time");
        List<WebUserInfo> adoptInfos = this.list(queryWrapper);
        PageInfo<WebUserInfo> pageResult = new PageInfo<>(adoptInfos);
        return pageResult;
    }

    @Override
    public WebUserInfo queryByOpenId(String openId) {
        QueryWrapper<WebUserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("open_id", openId);
        return this.getOne(queryWrapper);
    }

    @Override
    public Map<String, Object> query4Stat() {
        String tenantId = SessionUtils.getTenantId();
        QueryWrapper<WebUserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tenant_id", tenantId);
        queryWrapper.isNotNull("gender");
        List<WebUserInfo> allUsers = this.list(queryWrapper);


        LocalDate today = LocalDate.now();

        LocalDate yesterday = today.plusDays(-1);
        List<WebUserInfo> yesterdayUsers = allUsers.stream().filter(item -> item.getCreateTime().toLocalDate().isEqual(yesterday)).collect(Collectors.toList());
        List<WebUserInfo> todayUsers = allUsers.stream().filter(item -> item.getCreateTime().toLocalDate().isEqual(today)).collect(Collectors.toList());


        Map<String, Object> map = new HashMap<>();
        Map<String, Integer> userQuantity = new HashMap<>();

        userQuantity.put("total", allUsers.size());
        userQuantity.put("today", todayUsers.size());
        userQuantity.put("yesterday", yesterdayUsers.size());

        map.put("userQuantity", userQuantity);


        Map<String, Long> accessQuantity = new HashMap<>();
        List<QxUserAccess> qxUserAccesses = userAccessService.listAllAccessByTenantId(tenantId);
        if (CommonUtils.isNull(qxUserAccesses)) {
            qxUserAccesses = new ArrayList<>();
        }


        List<QxUserAccess> yesterdayAccess = qxUserAccesses.stream().filter(item -> item.getAccessDay().isEqual(yesterday)).collect(Collectors.toList());
        if (!CommonUtils.isNull(yesterdayAccess)) {
            accessQuantity.put("yesterday", yesterdayAccess.get(0).getTotal());
        } else {
            accessQuantity.put("yesterday", 0L);
        }
        List<QxUserAccess> todayAccess = qxUserAccesses.stream().filter(item -> item.getAccessDay().isEqual(today)).collect(Collectors.toList());
        if (!CommonUtils.isNull(todayAccess)) {
            accessQuantity.put("today", todayAccess.get(0).getTotal());
        } else {

            QxUserAccess userAccessTodayInCache = new QxUserAccess();
            try {
                Set<String> keys = ZeroCacheUtils.getKeys(QxContant.getWxAccessUserNumPrefix() + tenantId + ":" + "*");

                if (CommonUtils.isNull(keys)) {
                    userAccessTodayInCache.setTotal(0L);
                } else {
                    userAccessTodayInCache.setTotal(Long.valueOf(keys.size()));
                }

            } catch (Exception e) {
                userAccessTodayInCache.setTotal(0L);
                e.printStackTrace();
            }
            userAccessTodayInCache.setTenantId(tenantId);
            userAccessTodayInCache.setAccessDay(LocalDate.now());
            qxUserAccesses.add(userAccessTodayInCache);
            accessQuantity.put("today", userAccessTodayInCache.getTotal());
        }
        Long total = qxUserAccesses.stream().collect(Collectors.summingLong(QxUserAccess::getTotal));
        accessQuantity.put("total", total);
        map.put("accessQuantity", accessQuantity);
        List<Long> userAccessQuantityList = new ArrayList<>();
        for (int i = -14; i <= 0; i++) {
            final Integer before = i;
            LocalDate key = today.plusDays(before);
            List<QxUserAccess> tempAccess = qxUserAccesses.stream().filter(item -> item.getAccessDay().isEqual(key)).collect(Collectors.toList());
            if (CommonUtils.isNull(tempAccess)) {
                userAccessQuantityList.add(0L);
            } else {
                userAccessQuantityList.add(tempAccess.get(0).getTotal());
            }

        }
        map.put("accessQuantityList", userAccessQuantityList);
        return map;
    }

    @Override
    public String getOpenIdByUserId(String userId) {
        return this.getById(userId).getOpenId();
    }

    @Override
    public WebUserInfoDetailVo getWebUserDetailById(IdDto idDto) {
        WebUserInfo info = this.getById(idDto.getId());

        if (CommonUtils.isNull(info)) {
            throw new BizException("没有找到对应的用户");
        }
        WebUserInfoDetailVo detailVo = new WebUserInfoDetailVo();
        BeanUtil.copyProperties(info, detailVo);
        String userId = info.getId();

        WebUserAccount account = webUserAccountService.getAccountByUserId(userId);
        BigDecimal userAccount = new BigDecimal(BigInteger.ZERO);
        if (!CommonUtils.isNull(account) && !CommonUtils.isNull(account.getUserAccount())) {
            userAccount = account.getUserAccount();
        }
        detailVo.setUserAccount(userAccount);
        return detailVo;
    }

}
